#include <QtPlugin>
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QDoubleSpinBox>
#include <QSpinBox>
#include <QComboBox>
#include <QMessageBox>
#include <QCheckBox>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>

#include <opencv/cv.h>
#include <opencv/highgui.h>

#include "QCVModuleInterface.h"
#include "QCVModuleHandlerInterface.h"

#ifndef MODULE_SIFT
#define MODULE_SIFT

/**
@class ModuleSIFT
@brief Module de detection d'invarents d'echelle et|ou extraction de descripteurs
*/
class ModuleSIFT:public QObject,QCVModuleInterface
{
  Q_OBJECT
	Q_INTERFACES(QCVModuleInterface)
	
	public:
		void init(QCVModuleHandlerInterface * parent);
		void free();
		void loadParams(QString filename);
		void saveParams(QString filename);

		cv::Mat & process();
		void setInput(int n,const cv::Mat & m);

		QWidget* widget();
		QString getName();
		int nbInputs();
		QString help(int id);

		bool setParams(QString params);
		QString getParams();
	
		QCVModuleInterface * clone();

  private slots:
    void changeSIFTParams(double n);
    void changeSIFTParams(int n);
    void setSIFTParams(int type);
    void load();
    void save();
    
  private:  
    QWidget * win;
    QVBoxLayout * layout;
    QComboBox * mode;
    QCheckBox * use_mask,*recalculateAngles,*isNormalize;
    
    QLabel *descr_params,*detec_params,*common_params;
    
    QPushButton *pb_load,*pb_save;
    QSpinBox *sb_nOctaves,*sb_nOctaveLayers,*sb_firstOctave,*sb_angleMode;
    QDoubleSpinBox * sb_threshold,*sb_edgeThreshold;
    QDoubleSpinBox * magnification;
    std::vector<cv::KeyPoint> siftTargets;
    cv::Mat frame,mask,descriptors;
    cv::Mat_<float> keypoints;
    
    cv::SIFT * sift;
    
    QCVModuleHandlerInterface * parent;
};

#endif
